// 题目描述
// 给你一个字符数组 chars ，请使用下述算法压缩：

// 从一个空字符串 s 开始。对于 chars 中的每组 连续重复字符 ：

// 如果这一组长度为 1 ，则将字符追加到 s 中。
// 否则，需要向 s 追加字符，后跟这一组的长度。
// 压缩后得到的字符串 s 不应该直接返回 ，需要转储到字符数组 chars 中。需要注意的是，如果组长度为 10 或 10 以上，则在 chars 数组中会被拆分为多个字符。

// 请在 修改完输入数组后 ，返回该数组的新长度。

// 你必须设计并实现一个只使用常量额外空间的算法来解决此问题。



// 示例 1：

// 输入：chars = ["a","a","b","b","c","c","c"]
// 输出：返回 6 ，输入数组的前 6 个字符应该是：["a","2","b","2","c","3"]
// 解释："aa" 被 "a2" 替代。"bb" 被 "b2" 替代。"ccc" 被 "c3" 替代。
// 示例 2：

// 输入：chars = ["a"]
// 输出：返回 1 ，输入数组的前 1 个字符应该是：["a"]
// 解释：唯一的组是“a”，它保持未压缩，因为它是一个字符。
// 示例 3：

// 输入：chars = ["a","b","b","b","b","b","b","b","b","b","b","b","b"]
// 输出：返回 4 ，输入数组的前 4 个字符应该是：["a","b","1","2"]。
// 解释：由于字符 "a" 不重复，所以不会被压缩。"bbbbbbbbbbbb" 被 “b12” 替代。

let arr = ["a", "a", "b", "b", "c", "c", "c", "c", "c", "c", "c", "c", "c", "c", "c", "c"]

// 不改变原数组的版本：
// 自己的答案（能运行，但评分低
/**
 * @param {character[]} chars
 * @return {number}
 */
var compress = function (chars) {
    if (chars.length === 1) return chars.length
    let map = [];
    let mapIndex = 1
    let count = 1
    for (let i = 0; i < chars.length; i++) {
        if (chars[i] === chars[i + 1]) {
            count++
        } else  {
            ++mapIndex
            map.push([chars[i],count])
            count = 1
        }
    }

    while (chars.length > 0) {
        chars.pop();
    }
    let tempArr = map.map(item => {
        if (item[1] === 1) {
            item[1] = ''
        }
        return item
    }).flat().map(e => e.toString().split('')).flat().filter(item => item !== '')
    chars.push(...tempArr)
    return chars.length
};

// Gpt答案：
/**  
 * @param {character[]} chars  
 * @return {number}  
 */  
var compress = function(chars) {  
    if (chars.length === 1) return 1;  
  
    let result = '';  
    let count = 1;  
  
    for (let i = 0; i < chars.length; i++) {  
        if (i + 1 < chars.length && chars[i] === chars[i + 1]) {  
            count++;  
        } else {  
            result += chars[i] + (count > 1 ? count.toString() : '');  
            count = 1;  
        }  
    }  
  
    // 直接在 chars 数组上清空并填充新的压缩结果  
    chars.splice(0, chars.length, ...result.split(''));  
    return chars.length;  
    // return result.split('').length; // 不改变原数组
};

// 改变原数组的版本：
// 自己的答案（能运行，但评分低）：
/**  
 * @param {character[]} chars  
 * @return {number}  
 */  
var compress = function (chars) {
    let count = 1 // 初始化要删除个数的数组的每个项目
    let deleteCountsArr = [] // 初始化要删除个数的数组
    let i = chars.length // 原数组长度
    let n = 0 // 在去重后的原数组中为每个项后面添加个数时若遇到需要添加的数字为1或者超过1位数（例如10,11），需要 splice 的位数
    // let map = new Map();
    // for (let i = 0; i < chars.length; i++) { // 得到要删除个数的数组
    //     if (chars[i] === chars[i + 1]) {
    //         count++
    //     } else {
    //         deleteCountsArr.push(count)
    //         count = 1
    //     }
    // }
    while (i--) { // 得到去重后的原数组
        if (chars[i] === chars[i - 1]) {
            chars.splice(i, 1);
            count++
        } else if (i !== chars.length && chars[i] !== chars[i + 1]) {
            console.log(i)
            deleteCountsArr.unshift(count.toString()) // 得到要删除个数的数组（简化了上面注释的方法）
            count = 1
        }
    }
    if(chars.length === 1) {
        return chars.length
    }
    console.log(deleteCountsArr)
    for (let i = 0; i < deleteCountsArr.length; i++) { // 通过“要删除个数的数组”在去重后的原数组中的每个项后面添加个数
        if (deleteCountsArr[i].length > 1) {
            chars.splice(2 * i + 1 + n, 0, ...deleteCountsArr[i].split(''));
            n += deleteCountsArr[i].length - 1 // 遇到需要添加的数字超过1位数
        } else if(deleteCountsArr[i] === '1') { // 遇到需要添加的数字为1
            --n
        } else {
            chars.splice(2 * i + 1 + n, 0, deleteCountsArr[i]);
        }
    }
    return chars.length
};

console.log(compress(arr), arr)

// 官方答案
var compress = function(chars) {
    let p1 = 0, p2 = 1, str = ''

    while (p1 < chars.length) {
        if (chars[p1] === chars[p2]) {
            p2++
        } else if (chars[p1] !== chars[p2]) {
            str += (chars[p1] + (p2 - p1 === 1 ? '' : (p2 - p1)))
            p1 = p2
            p2 = p1 + 1
        }
    }
    let len = str.split('').length
    chars.splice(0, len)
    chars.unshift(...str.split(''))
    return len
};